package sparrowGui.components
{
	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;
	
	import sparrowGui.components.item.ItemFactory;
	import sparrowGui.components.item.SItem;
	import sparrowGui.i.IItem;
	import sparrowGui.i.IItemFactory;
	import sparrowGui.i.IItemGroup;

	/**
	 * 项组组件
	 * 有项的创建，更新，排列等方法。单多选组件扩展此对象
	 * @author Pelephone
	 * @website http://cnblogs.com/pelephone
	 */
	public class ItemGroup extends BaseUIComponent implements IItemGroup
	{
		private static const ITEM_PREFIX:String = "item_prefix";	//项前缀
		
		private var _colNum:int = 1;
		private var _colWidth:int;
		private var _rowHeight:int;
		private var _spacing:int;
		/**
		 * 项创建工厂
		 */
		private var itemFactory:IItemFactory;
		
		/**
		 * 项组
		 */
		protected var itemLs:Vector.<IItem>;
		/**
		 * 项名称绑定的哈希关系对象
		 */
		protected var itemHash:Object;
		
		public function ItemGroup(uiVars:Object=null,cellFactory:IItemFactory=null)
		{
			super(uiVars);
			if(cellFactory == null)
				this.itemFactory = new ItemFactory(SItem,"GroupItem");
			else
				this.itemFactory = cellFactory;
			
			itemLs = new Vector.<IItem>();
		}
		
/*		override protected function create(uiVars:Object=null):void
		{
			
		}
		*/
		
		public function update(data:Object):void
		{
			
		}
		
		/**
		 * 通过皮肤显示对象组生成项(通过此方法可以不用把子项镶入组件中也可以操作)
		 * @param skinLs
		 */
		public function createItemsBySkins(skinLs:Array):void
		{
			itemLs = new Vector.<IItem>();
			itemHash = {};
			for (var i:int = 0; i < skinLs.length; i++) 
			{
				var itmSkin:DisplayObject = skinLs[i] as DisplayObject;
				var itm:IItem = createNewItem(itmSkin);
				itemLs.push(itm);
				itemHash[itm.name] = itm;
			}
			addSkinListen();
		}
		
		public function createItems(size:int):void
		{
			// 皮肤不是容器就不能生成
			if(!skinDC) return;
			itemLs = new Vector.<IItem>();
			itemHash = {};
			for (var i:int = 0; i < size; i++) 
			{
				var itm:IItem = createNewItem();
				itm.name = ITEM_PREFIX + i;
				addItem(itm);
			}
		}
		
		public function updateItems(data:Object):void
		{
			for (var oName:Object in data) 
			{
				var itm:IItem;
				if(typeof(oName)=="number")
					itm = getItemAt(int(oName));
				else
					itm = getItemByName(String(oName));
				
				if(!itm) continue;
				var vo:Object = data[oName] as Object;
				updateItem(itm,vo);
			}
		}
		
		/**
		 * 排列所有项
		 */
		public function arrangeItems():void
		{
			// 有遍历可能会吃性能
/*			var itmSkinLs:Array = [];
			for each (var itm:IItem in itemLs) 
				itmSkinLs.push(itm.skin);
			
			SparrowUtil.arrangeDispRC(itmSkinLs,colNum,colWidth,rowHeight,spacing);*/
			
			
			var tmpY:int=0,tmpX:int=0;
			var i:int = 0;
			for each (var itm:IItem in itemLs) 
			{
				var dp:DisplayObject = itm.skin;
				if(!dp) continue;
				if(i && !(i%colNum) && colNum!=0){
					tmpY = tmpY + spacing + (rowHeight?rowHeight:dp.height);
					tmpX = 0;
				}
				dp.x = tmpX;
				tmpX = tmpX + (colWidth || dp.width) + spacing;
				dp.y = tmpY;
				i++;
			}
		}
		
		/**
		 * 移除所有项
		 */
		public function removeAllItems():void
		{
			for each (var itm:IItem in itemLs) 
			{
				itemFactory.disposeItemSkin(itm.skin);
				itemFactory.disposeItem(itm);
			}
			itemLs = new Vector.<IItem>();
			itemHash = {};
		}
		
		protected function createNewItem(uiVars:DisplayObject=null):IItem
		{
			uiVars = uiVars || createNewItemSkin();
			return itemFactory.createNewItem(uiVars);
		}
		
		protected function createNewItemSkin():DisplayObject
		{
			return itemFactory.createNewItemSkin();
		}
		
		/**
		 * 添加项
		 * @param itm
		 * @return 
		 */
		public function addItem(itm:IItem):IItem
		{
			skinDC.addChild(itm.skin);
			itemLs.push(itm);
			itemHash[itm.name] = itm;
			return itm;
		}
		
		/**
		 * 更新子项数据
		 * @param itm
		 * @param data
		 */
		protected function updateItem(itm:IItem,data:Object=null):void
		{
			itm.update(data);
		}
		
		/**
		 * 指定位置加入项
		 * @param itm
		 * @param index
		 */
		public function addItemAt(itm:IItem,index:int):IItem
		{
			if(index>=itemLs.length && index<0) return null;
			itemLs.splice(index, 0, itm);
			itemHash[itm.name] = itm;
			return itm;
		}
		
		/**
		 * 移出某位置上的项
		 * @param index
		 */
		public function removeItemAt(index:int):IItem
		{
			if(index>=itemLs.length && index<0) return null;
			var itm:IItem = itemLs.splice(index,1)[0];
			itemHash[itm.name] = null;
			delete itemHash[itm.name];
			return itm;
		}
		
		/**
		 * 移出某项
		 * @param itm
		 */
		public function removeItem(itm:IItem):IItem
		{
			var itm:IItem = itemHash[itm.name];
			if(!itm) return null;
			var index:int = itemLs.indexOf(itm);
			return removeItemAt(index);
		}
		
		protected function get skinDC():DisplayObjectContainer
		{
			return skin as DisplayObjectContainer;
		}
		
		override public function dispose():void
		{
			super.dispose();
			itemFactory = null;
			itemLs = null;
			itemHash = null;
		}
		
		/**
		 * 改变按钮生成工厂
		 * @param newFactory 新的按钮生成工厂
		 */
		public function setItemFactory(newFactory:IItemFactory):void{
			itemFactory = newFactory;
		}
		
		public function set itemSkinClass(value:Class):void
		{
			itemFactory.itemSkinClass = value;
		}
		
		/////////////////////////////////////////
		// get/set
		/////////////////////////////////////////
		
		/**
		 * 通过项index获取项(data是数组的时候可用,如果data是哈希数据,可以用getItemByArgs)
		 */
		public function getItemAt(index:int):IItem
		{
			return itemLs[index] as IItem;
		}
		/**
		 * 通过名称查找对应的项
		 * @param itemName
		 */
		public function getItemByName(itemName:String):IItem
		{
			return itemHash[itemName] as IItem;
		}
		
		override public function getDefaultUIName():String
		{
			return "ItemGroup";
		}

		/**
		 * 每行有的列数,如列表组件一般是每行1列
		 */
		public function get colNum():int
		{
			return _colNum;
		}

		/**
		 * @private
		 */
		public function set colNum(value:int):void
		{
			_colNum = value;
		}

		/**
		 * 列宽
		 */
		public function get colWidth():int
		{
			return _colWidth;
		}

		/**
		 * @private
		 */
		public function set colWidth(value:int):void
		{
			_colWidth = value;
		}

		/**
		 * 行高
		 */
		public function get rowHeight():int
		{
			return _rowHeight;
		}

		/**
		 * @private
		 */
		public function set rowHeight(value:int):void
		{
			_rowHeight = value;
		}

		/**
		 * 行列间隔
		 */
		public function get spacing():int
		{
			return _spacing;
		}

		/**
		 * @private
		 */
		public function set spacing(value:int):void
		{
			_spacing = value;
		}
		
		public function get itemLength():int
		{
			return itemLs.length;
		}
	}
}